class Node {
	constructor (element, next = null) {
		this.next = next;
		this.element = element;
	}

	setNext (next = null) {
		this.next = next;
	}

	setElement (element) {
		this.element = element;
	}
}

class LinkedList {
	constructor () {
		this.size = 0;
		this.head = null;
	}

	add (index, element) {
		if (arguments.length == 1) {
			element = index
			index = this.size
		}
		if (index < 0 || index > this.size) {
			throw new Error('cross the border')
		}
		const node = new Node(element);
		if (index == 0) {
			node.setNext(this.head);
			this.head = node;
		} else {
			const prev = this.get(index - 1);
			node.setNext(prev.next);
			prev.next = node; // 插入节点数据
		}

		++this.size
	}

	remove (index = this.size - 1) {
		if (!this.size || index >= this.size) {
			throw new Error('cross the border')
		}
		let current = this.head;
		--this.size;

		if (index === 0) {
			this.head = current.next;
		} else {
			const prevState = this.get(index - 1);
			current = prevState.next;
			prevState.setNext(current.next);
		}
		return current;
	}

	getSize () {
		return this.size;
	}

	get (index) {
		if (index < 0 || index > this.size) {
			throw new Error('cross the border')
		}
		let current = this.head;
		for (let i = 0; i < index; i++) {
			current = current.next
		}
		return current;
	}

	set (index, element) {
		this.get(index).setElement(element);
	}

	clear () {
		this.size = 0;
		this.head = null;
	}

	traversal () {
		const queue = [];
		let current = this.head;
		while (current) {
			queue.push(current.element);
			current = current.next;
		}
		console.log(queue);
	}

	getRear () {
		return this.get(this.size - 1);
	}
}

class Queue {
	constructor () {
		this.linked = new LinkedList()
	}

	enQueue (data) {
		this.linked.add(data)
	}

	deQueue () {
		if (this.getSize() >= 1) {
			return this.linked.remove(0);
		}
	}

	getSize () {
		return this.linked.getSize();
	}

	traversal () {
		this.linked.traversal()
	}
}

class Stack {
	constructor () {
		this.linked = new LinkedList()
	}

	enStack (data) {
		this.linked.add(data)
	}

	deStack () {
		if (this.getSize() >= 1) {
			return this.linked.remove();
		}
	}

	getSize () {
		return this.linked.getSize();
	}

	traversal () {
		this.linked.traversal()
	}
}

module.exports = {
	Queue,
	Stack,
	LinkedList,
}


